package com.iqiyi.pps.epg.web.timer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iqiyi.pps.epg.core.model.channel.ChannelBase;
import com.iqiyi.pps.epg.core.model.channel.ChannelConfig;
import com.iqiyi.pps.epg.core.model.stream.LiveChannelStream;
import com.iqiyi.pps.epg.core.model.stream.LiveStream;
import com.iqiyi.pps.epg.core.rpc.qipu.impl.QipuManager;
import com.iqiyi.pps.epg.core.service.channel.ChannelService;
import com.iqiyi.pps.epg.core.service.stream.LiveChannelStreamService;
import com.iqiyi.pps.epg.core.service.stream.LiveStreamService;
import com.iqiyi.pps.epg.core.utils.ApiHttpRequestUtil;
import com.iqiyi.pps.epg.core.utils.OuterApiUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * Created by Lemuel on 2016/7/28.
 */
public final class StreamCompletionTrigger {
    private static final Logger logger = LoggerFactory.getLogger(QipuManager.class);
    private final static String infoChannel = String.format(OuterApiUtil.BASE_URL_CUTTER, "infochannel");
    private final static String STREAM_COMPLETION_CONFIG = "streamComplete";
    private final static int DELETE_OPERATION_KEY = 1;
    private final static int CONFIG_KEY = 0;

    @Autowired
    private LiveStreamService liveStreamService;

    @Autowired
    private LiveChannelStreamService liveChannelStreamService;

    @Autowired
    private ChannelService channelService;

    @Autowired
    private QipuManager qipuManager;

    public void task() {
        logger.info("[StreamCompletionTrigger][task][start]");
        StreamConfig config = getConfig();
        if (null == config || !config.isOn()) {
            logger.info("[StreamCompletionTrigger][task][end][not on]");
            return;
        }

        List<LiveChannelStream> liveChannelStreamList = liveChannelStreamService.getEnableChannelStream();
        for(LiveChannelStream channelStream : liveChannelStreamList) {
            try {
                String flvUrl = checkHadHcdnlive(channelStream.getFatherId(), channelStream.getStreamName());
                if (StringUtils.isEmpty(flvUrl)){
                    logger.info("[StreamCompletionTrigger][task][already had hlflv][fatherId={}][streamName={}]",
                            channelStream.getFatherId(), channelStream.getStreamName());
                    continue;
                }

                String hcdnlive = fetchHcdnlive(flvUrl);

                if (StringUtils.isEmpty(hcdnlive)) {
                    logger.info("[StreamCompletionTrigger][task][can't fetch hcdnlive][fatherId={}][streamName={}]",
                            channelStream.getFatherId(), channelStream.getStreamName());
                    continue;
                }

                LiveStream liveStreamHlflv = new LiveStream();
                liveStreamHlflv.setFatherId(channelStream.getFatherId());
                liveStreamHlflv.setStreamName(channelStream.getStreamName());
                liveStreamHlflv.setUuid(UUID.randomUUID().toString());
                liveStreamHlflv.setFormatType(LiveStream.FORMATTYPE_HLFLV);
                liveStreamHlflv.setUrl(hcdnlive);
                liveStreamHlflv.setIsDefault(false);
                liveStreamService.save(liveStreamHlflv);

                ChannelBase channelBase = channelService.getChannelBase(channelStream.getFatherId());
                addStreamToQipu(channelBase.getQipuId(), liveStreamHlflv);
            } catch (Exception e) {
                logger.info("[StreamCompletionTrigger][task][exception] " + e);
            }
        }

        logger.info("[StreamCompletionTrigger][task][end][execute finished]");

    }

    public static String fetchHcdnlive(String ch) {
        Map<String, Object> params = new HashMap<>();
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", "2.0");
        params.put("ch", ch);

        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(infoChannel, params);
        if (null == jsonObject || "0".equals(jsonObject.getString("status"))) {
            return StringUtils.EMPTY;
        }

        JSONObject data = jsonObject.getJSONObject("data");

        return data.getString("hcdnlive_url");
    }


    private StreamConfig getConfig() {
        List<ChannelConfig> channelConfigList = channelService.getConfig(STREAM_COMPLETION_CONFIG);
        if (null == channelConfigList || channelConfigList.size() == 0) {
            return null;
        }

        doDeleteOperation(channelConfigList);

        StreamConfig config = null;
        try {
            String configString = getConfigString(channelConfigList);
            config = JSONObject.parseObject(configString, StreamConfig.class);
        } catch (Exception e) {
            logger.info("[StreamCompletionTrigger][task][getConfig][exception]" + e);
            return null;
        }

        return config;
    }

    private void doDeleteOperation(List<ChannelConfig> channelConfigList) {
        for (ChannelConfig config : channelConfigList) {
            if (config.getKey() == DELETE_OPERATION_KEY) {
                deleteStreamToQipu(Long.valueOf(config.getVal()), config.getDescr());
            }
        }
    }

    private static String getConfigString(List<ChannelConfig> channelConfigList) {
        for (ChannelConfig config : channelConfigList) {
            if (config.getKey() == CONFIG_KEY) {
                return config.getVal();
            }
        }
        return "{}";
    }

    // Returns the empty string if had, flv url otherwise.
    private String checkHadHcdnlive(long fatherId, String streamName) {
        logger.info("[StreamCompletionTrigger][checkHadHcdnlive][fatherId={}][streamName={}]", fatherId, streamName);
        List<LiveStream> streamList = liveStreamService.get(fatherId, streamName);
        String ch = "";
        for (LiveStream stream : streamList) {
            if (LiveStream.FORMATTYPE_HLFLV.equals(stream.getFormatType())){
                return StringUtils.EMPTY;
            } else if (LiveStream.FORMATTYPE_FLV.equals(stream.getFormatType())) {
                ch = stream.getUrl();
            }
        }
        return ch;

    }

    private void addStreamToQipu(Long qipuId, LiveStream liveStreamData) {
        logger.info("[StreamCompletionTrigger][addstreamToQipu][qipuId={}][liveStream={}]",
                qipuId, JSON.toJSONString(liveStreamData));
       qipuManager.addLiveStreamToQipu(qipuId, liveStreamData);

    }

    private void deleteStreamToQipu(Long qipuId, String uuid) {
        logger.info("[StreamCompletionTrigger][addstreamToQipu][qipuId={}][uuid={}]", qipuId, uuid);
        qipuManager.delLiveStreamToQipu(qipuId, uuid);
    }

    private static class StreamConfig {
        private String status = "OFF";
        private String extraAdd = "";
        private String extraDelete = "";

        public boolean isOn () {
            return status.equals("ON");
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public String getExtraAdd() {
            return extraAdd;
        }

        public void setExtraAdd(String extraAdd) {
            this.extraAdd = extraAdd;
        }

        public String getExtraDelete() {
            return extraDelete;
        }

        public void setExtraDelete(String extraDelete) {
            this.extraDelete = extraDelete;
        }
    }


}
